from collections import defaultdict
import functools
import h5py
import numpy as np


def groupby(iterable, key):
    groups = defaultdict(list)
    for item in iterable:
        groups[key(item)].append(item)
    return groups


def read_from_h5_file_with_cache(h5_file_path):
    h5_file_obj = h5py.File(h5_file_path, 'r',)

    @functools.lru_cache(None)
    def helper(path):
        return h5_file_obj[path][...]
    return helper


def normalization(vmin, vmax):
    def helper(x):
        x = np.asarray(x)
        x = np.clip(x, vmin, vmax)
        x = (x - vmin) / (vmax - vmin)
        return x
    return helper


def append_axis():
    def helper(x):
        x = np.asarray(x)
        return x[..., None]
    return helper


def astype(dtype):
    def helper(x):
        x = np.asarray(x, dtype=dtype)
        return x
    return helper
